'use strict';
/**
 * 莫凡服务端中间键：后端解密操作，暂时忽略前端部分路由
 * @version 1.0.0
 * @author hxx xiech
 * @Time 2019年11月20日09:54:49
 */

const NodeRSA = require("node-rsa");
const MD5 = require('md5-node');
const _priKey = `-----BEGIN RSA PRIVATE KEY-----
                 MIICWwIBAAKBgQDGNrzOW3wuyy88mWM5C5pWXhP5IukJUu3j7cUnYHGsCQeuH2Dj
                 YXnub583DWeaUN1hpNPHvAXfXj8Zl8/E/VZv3NLyejs4o6g1wCP1msTRKubJwznX
                 Lza6tnwAo6/IjpnR5/ngOSdsPtz8QYcpC9VF4MZA35uaZLBqUwzBkI3gSwIDAQAB
                 AoGAWL2W6BhjT5veCRZvKtH8BiDWdlrf1DHRmZMRCmEOY0QjsRwRR5uTeGF2+bHB
                 qX/8rUObITgXtPo/69hgx8PYFzEEuUh/5Z/9Lk8Ky2X6OgnxWjHX4qzRudYeFu0i
                 c/JF4Mh/oSkAS/u1rNxQEpj6lKo5Q7gNBZK9jJRC9aHc6AkCQQDpZqVw5e119+D7
                 N/XefUopCsqwWwz5Llj5tiQdOZrXwgOmlGltbn8DFhTbJVJSn2fc8zL9ymXKcCyF
                 JkA1LEkHAkEA2WfmoRgYcZIoUnmprs+wgHkY7tFiPyNcyqwmA46pAm3bjI79QEsC
                 Znipc9zllyWAlKjwbrgoyEG7CSfmaU9xnQJAd9b+h3Nnc7TszdCz66NFGsGxxM9b
                 X+5OPRkqfd8ABFxX54Y4g7nCeWEzIDqPhGDYwXgV7H2pukHSeiNjwGmWrQJAJb9f
                 kOrxG48IB0Huj1aqS7Q6+wRJ7bKDIwF+3DFB8RUIAMC3AhnEAezDZ0Wca4DscWNf
                 06mQEy0uf2l5HSHZFQJAYaTZwR4vhv4YxlE8dy7fhEijzlWIkBn4BdP+8rZiEf9c
                 zMbeB5BGGPcseGt08EqK1wYPjh5N3nEUumS/KkFAfQ==
                 -----END RSA PRIVATE KEY-----`;
module.exports = () => {
	return async function(ctx, next) {
		try {
			let headerData = ctx.request.header;
			let pData = {
				success: false
			};
			if (ctx.request.header.sign) {
				let obj = null;
				let requestData = null;
				if (ctx.request.method == "POST" || ctx.request.method == "post") {
					obj = `${headerData.mfrequestid}Xwb5COdSD5u5vHOpIacsepdJPlkwREu7c-e1gNYxb${JSON.stringify(objKeySort(ctx.request.body))}${headerData.mfrequesttime}`;
					requestData = ctx.request.body;
				} else {
					requestData = ctx.request.query;
					obj = `${headerData.mfrequestid}Xwb5COdSD5u5vHOpIacsepdJPlkwREu7c-e1gNYxbparams=${requestData.params}${headerData.mfrequesttime}`;
				}

				let signStr = MD5(obj).toUpperCase();
				if (headerData.mfrequestid && headerData.mfrequesttime) {
					if (signStr != headerData.sign) { //  验签参数验证
						ctx.body = await ctx.helper.basicode(500004, pData);
					} else if (new Date().getTime() - Number(headerData.mfrequesttime) > 10000) { //  请求时间超时判断
						ctx.body = await ctx.helper.basicode(500003, pData);
					} else {
						if (requestData && requestData.params) {
							try {
								const privateKey = new NodeRSA(_priKey);
								let res2 = privateKey.decrypt(requestData.params, "utf8");
								if (ctx.request.method == "POST" || ctx.request.method == "post") {
									ctx.request.body = JSON.parse(res2);
								} else {
									ctx.request.query = JSON.parse(res2);
								}
								await next();
							} catch (e) {
								ctx.body = await ctx.helper.basicode(500005, pData);
							}
						} else {
							ctx.body = await ctx.helper.basicode(500006, pData);
						}
					}
				} else {
					ctx.body = await ctx.helper.basicode(500002, pData);
				}
			} else {
				ctx.body = await ctx.helper.basicode(500001, pData);
			}
		} catch (err) {
			console.log('sync function userInterceptor-error', err);
			ctx.body = await ctx.helper.basicode(900001, pData);
		}
	};
};

//排序的函数
function objKeySort(obj) {
	let newkey = Object.keys(obj).sort();
	//先用Object内置类的keys方法获取要排序对象的属性名，再利用Array原型上的sort方法对获取的属性名进行排序，newkey是一个数组
	let newObj = {}; //创建一个新的对象，用于存放排好序的键值对
	for (let i = 0; i < newkey.length; i++) { //遍历newkey数组
		newObj[newkey[i]] = obj[newkey[i]]; //向新创建的对象中按照排好的顺序依次增加键值对
	}
	return newObj; //返回排好序的新对象
}